#include "mybutton.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPixmap>
#include <QBitmap>
#include "Qt"
#include "QWidget"
#include "qdebug.h"
#include "stdlib.h"
#include "QPoint"
#include "QPropertyAnimation"
#include "MyAnimation.h"
#include "QMessageBox"
#include "math.h"
using namespace std;
static double RX = 1600.0/750;
static double RY = 900.0/50;
MyButton::MyButton(QWidget *parent,int m,int n,int Data)://根节点构造
    QPushButton(parent)
{
    this->father = NULL;
    this->lchild = NULL;
    this->rchild = NULL;
    this->Height = 0;
    this->parent_widget = parent;
    this->Data = Data;
    pixmap = new QPixmap(this->resPathstatic);
    *pixmap = pixmap->scaled(radius,radius,Qt::KeepAspectRatio,Qt::SmoothTransformation);
    this->resize(pixmap->size());

    QString str;
    str = str.sprintf("%d",Data);
    this->setText(str);

    move(m,n);
    QWidget *widget = nullptr;
    widget = parent_widget;
    /* 设置按钮的有效区域 */
    setMask(QBitmap(*pixmap));
    setStyleSheet("QPushButton{border-image: url("+resPathstatic+");}");
    convert_vector(widget);
    res_position();
}
MyButton::MyButton(QWidget *parent,MyButton* father,int direct,int Data)://子节点构造
    QPushButton(parent)
{
    this->lchild = NULL;
    this->rchild = NULL;
    this->father = father;
    this->Height = 0;
    this->parent_widget = parent;
    this->direct = direct;
    this->Data = Data;
    pixmap = new QPixmap(resPathstatic);
    *pixmap = pixmap->scaled(radius,radius,Qt::KeepAspectRatio,Qt::SmoothTransformation);
    this->resize(pixmap->size());

    QString str;
    str = str.sprintf("%d",Data);
    this->setText(str);

    QPoint p = positionForParent(father);
    move(p);
    /* 设置按钮的有效区域 */
    setMask(QBitmap(*pixmap));
    setStyleSheet("QPushButton{border-image: url("+resPathstatic+");}");
    convert_vector(this->parent_widget);
}

void MyButton::enterEvent(QEvent *)
{
    this->pixmap = new QPixmap(resPathstatic2);
    *pixmap = pixmap->scaled(radius,radius,Qt::KeepAspectRatio,Qt::SmoothTransformation);
    resize(pixmap->size());
    /* 设置按钮的有效区域 */
    //setMask(QBitmap(*pixmap));
    setStyleSheet("QPushButton{border-image: url("+resPathstatic2+");}");
}

void MyButton::leaveEvent(QEvent *)
{
    this->pixmap = new QPixmap(resPathstatic);
    *pixmap = pixmap->scaled(radius,radius,Qt::KeepAspectRatio,Qt::SmoothTransformation);
    resize(pixmap->size());
    /* 设置按钮的有效区域 */
    setMask(QBitmap(*pixmap));
    setStyleSheet("QPushButton{border-image: url("+resPathstatic+");}");
}
void MyButton::mousePressEvent(QMouseEvent *){
    this->DeleteButton(this,this->Data);
}
void MyButton::res_position(){//窗口大小变化节点位置动态变化

    move(this->parent_widget->geometry().width()/(r_x),this->parent_widget->geometry().height()/(r_y));
}
void MyButton::convert_vector(QWidget* wi){//转化相对坐标，记住坐标系数
    this->r_x = wi->width()/((double)this->x()*1.0);
    this->r_y = wi->height()/((double)this->y()*1.0);
}
QPoint MyButton::positionForParent(MyButton *p){//根据父节点确定坐标
    if(p==NULL) return QPoint(parent_widget->width()*1.0/RX,parent_widget->height()*1.0/RY);
    if(this->direct==-1) return QPoint(-100,-100);
    int dis = radius/2 * pow(2,this->Height);
    if(this->direct== 0){
        return QPoint(p->x()-dis,p->y()+radius/2+50);
    }else if(this->direct== 1){
        return QPoint(p->x()+dis,p->y()+radius/2+50);
    }
}
QPoint MyButton::getP(){
    return QPoint(this->x(),this->y());
}
QPoint MyButton::getCenter(){
    return QPoint(this->x()+radius/2,this->y()+radius/2);
}
QPropertyAnimation*  MyButton::MoveAni_Straight(QPoint desti){//直线移动
    QPropertyAnimation* pPosAnimation1 = new QPropertyAnimation(this, "pos");
    pPosAnimation1->setDuration(MainWindow::AniSpeed);
    pPosAnimation1->setStartValue((this->getP()));
    pPosAnimation1->setEndValue(desti);
    pPosAnimation1->setEasingCurve(QEasingCurve::InOutQuad);
    pPosAnimation1->start();
    move(desti);
    convert_vector(this->parent_widget);
    return animator = pPosAnimation1;
}
QPropertyAnimation* MyButton::MoveAni_Circle(QPoint p,MyAnimation::PathType type){//曲线移动动画
    MyAnimation *m_pMyAnmation = new MyAnimation(this, "pos", this->parent_widget);
    m_pMyAnmation->setDuration(MainWindow::AniSpeed);
    m_pMyAnmation->setStartValue(this->getP());
    m_pMyAnmation->setEndValue(p);
    m_pMyAnmation->setPathType(type);
    m_pMyAnmation->setEasingCurve(QEasingCurve::InOutQuad);
    m_pMyAnmation->start();

    move(p);
    convert_vector(this->parent_widget);
    return animator = m_pMyAnmation;
}
int MyButton::GetHeight(MyButton *TreeRoot){
    if (TreeRoot == NULL) return -1;
        else {
            return TreeRoot->Height;
        }
}
int MyButton::GetBalancedFactor(MyButton *TreeRoot)
{
    return GetHeight(TreeRoot->lchild) - GetHeight(TreeRoot->rchild);
}
void MyButton::UpdateHeight(MyButton *TreeRoot) {
    TreeRoot->Height = max(GetHeight(TreeRoot->lchild), GetHeight(TreeRoot->rchild)) + 1;
}
MyButton* MyButton::L(MyButton *TreeRoot){
    MyButton *temp = TreeRoot->rchild;
    temp->rchild = TreeRoot->rchild->rchild;
    if(TreeRoot->father != NULL)
    {
        if(TreeRoot->father->Data >= temp->Data){
            temp->direct = 0;
        }
        else {
            temp->direct = 1;
        }
    }

        TreeRoot->rchild = temp->lchild;
        if(temp->lchild != NULL)
        {
            temp->lchild->direct = 1;
            temp->lchild->father = TreeRoot;
        }
        temp->lchild = TreeRoot;
        TreeRoot->direct = 0;
        if(TreeRoot->father != NULL)
        {
            temp->father = TreeRoot->father;
        }
        else
        {
            temp->father = NULL;
        }
        TreeRoot->father = temp;
        UpdateHeight(TreeRoot);
        UpdateHeight(temp);

    Preorder_Ani(temp,finddirect::RD,MyAnimation::PathType::LinearPath);
    Preorder_Ani(TreeRoot,finddirect::ALL,MyAnimation::PathType::ArcPathR);
    return temp;
}
MyButton* MyButton::R(MyButton *TreeRoot){
    MyButton *temp = TreeRoot->lchild;
    temp->lchild = TreeRoot->lchild->lchild;
    if(TreeRoot->father != NULL)
    {
        if(TreeRoot->father->Data >= temp->Data){
            temp->direct = 0;
        }
        else {
            temp->direct = 1;
        }
    }
        TreeRoot->lchild = temp->rchild;
        if(temp->rchild != NULL)
        {
            temp->rchild->direct = 0;
            temp->rchild->father = TreeRoot;
        }
        temp->rchild = TreeRoot;
        TreeRoot->direct = 1;
        if(TreeRoot->father != NULL)
        {
            temp->father = TreeRoot->father;
        }
        else
        {
            temp->father = NULL;
        }
        TreeRoot->father = temp;
        UpdateHeight(TreeRoot);
        UpdateHeight(temp);
    Preorder_Ani(temp,finddirect::LD,MyAnimation::PathType::LinearPath);
    Preorder_Ani(TreeRoot,finddirect::ALL,MyAnimation::PathType::ArcPathL);
    return temp;
}
MyButton* MyButton::InsertNode(QWidget *parent,MyButton *TreeRoot,MyButton *father,int Data,int direct){
        if (TreeRoot == NULL)
        {
            TreeRoot = new MyButton(parent,father,direct,Data);
            if(direct == 0)
            TreeRoot->father->lchild = TreeRoot;
            else if(direct == 1)
            TreeRoot->father->rchild = TreeRoot;

            TreeRoot->show();
            return TreeRoot;
        }
        if (Data < TreeRoot->Data)
                {
                    InsertNode(parent,TreeRoot->lchild, TreeRoot,Data,0);
                    UpdateHeight(TreeRoot);
                    TreeRoot = Rotate(TreeRoot);
                }
                else if (Data > TreeRoot->Data)
                {
                    InsertNode(parent,TreeRoot->rchild, TreeRoot,Data,1);
                    UpdateHeight(TreeRoot);
                    TreeRoot = Rotate(TreeRoot);
                }
        else{
            QMessageBox:: StandardButton result= QMessageBox::information(NULL, "警告", "不能输入重复",QMessageBox::Yes);
        }
        return TreeRoot;
}
MyButton* MyButton::Rotate(MyButton *TreeRoot){
    if (GetBalancedFactor(TreeRoot) == 2)
    {
        if (GetBalancedFactor(TreeRoot->lchild) == 1||GetBalancedFactor(TreeRoot->lchild) == 0)
        {
            TreeRoot = R(TreeRoot);
            TreeRoot = FatherJudge(TreeRoot);
        }
        else if (GetBalancedFactor(TreeRoot->lchild) == -1) {
            TreeRoot->lchild = L(TreeRoot->lchild);
            TreeRoot->lchild->father->lchild = TreeRoot->lchild;
            TreeRoot = R(TreeRoot);
            TreeRoot = FatherJudge(TreeRoot);
        }
    }
    if (GetBalancedFactor(TreeRoot) == -2)
    {
        if (GetBalancedFactor(TreeRoot->rchild) == -1||GetBalancedFactor(TreeRoot->rchild) == 0)
        {
            TreeRoot = L(TreeRoot);
            TreeRoot = FatherJudge(TreeRoot);
        }
        else if (GetBalancedFactor(TreeRoot->rchild) == 1) {
            TreeRoot->rchild = R(TreeRoot->rchild);
            TreeRoot->rchild->father->rchild = TreeRoot->rchild;
            TreeRoot = L(TreeRoot);
            TreeRoot = FatherJudge(TreeRoot);
        }
    }
    return TreeRoot;
}
MyButton* MyButton::FatherJudge(MyButton *TreeRoot){
    if(TreeRoot->father != NULL)
    {
        if(TreeRoot->father->Data > TreeRoot->Data)
        {
            TreeRoot->father->lchild = TreeRoot;
            TreeRoot->father->rchild->father = TreeRoot->father;
        }
        else{
            TreeRoot->father->rchild = TreeRoot;
            TreeRoot->father->lchild->father = TreeRoot->father;
        }
    }
    return TreeRoot;
}
QPropertyAnimation* MyButton::Preorder_Ani(MyButton* node,int d,MyAnimation::PathType type){//前序遍历二叉树进行动画位移
    QPropertyAnimation* t = NULL;
    if(node!=NULL){
         switch (type) {
         case MyAnimation::PathType::LinearPath:
             t = node->MoveAni_Straight(node->positionForParent(node->father));
             break;
         default:
             t = node->MoveAni_Circle(node->positionForParent(node->father),type);

         }
         switch (d) {
            case finddirect::LD:
             Preorder_Ani(node->lchild,finddirect::ALL,type);
             break;
            case finddirect::RD:
            Preorder_Ani(node->rchild,finddirect::ALL,type);
            break;
            default:
             Preorder_Ani(node->lchild,finddirect::ALL,type);
             Preorder_Ani(node->rchild,finddirect::ALL,type);
             break;
         }
     }
    return t;
}
void MyButton::Traversal(MyButton *node){
    if(node->lchild != NULL){
        Preorder_Ani(node->lchild,-1,MyAnimation::PathType::LinearPath);
        Traversal(node->lchild);
    }
    if(node->rchild != NULL){
        Preorder_Ani(node->rchild,1,MyAnimation::PathType::LinearPath);
        Traversal(node->rchild);
    }
}
MyButton* MyButton::DeleteButton(MyButton *TreeRoot, int Data){
    QMessageBox:: StandardButton result= QMessageBox::information(NULL, "请确认", "是否要删除此节点",QMessageBox::Yes|QMessageBox::No);
    switch (result)
    {
    case QMessageBox::Yes:
            if(GetHeight(TreeRoot) == 0)
            {
                if(TreeRoot->father->Data > Data)
                {

                    TreeRoot->father->lchild = NULL;

                }else{

                    TreeRoot->father->rchild = NULL;

                }
                UpdateFatherHeight(TreeRoot->father);
                TreeRoot->deleteLater();

            }else{
                QMessageBox::information(NULL, "警告", "此节点无法删除！");
            }
        parent_widget->update();
        break;
    case QMessageBox::No:
        break;
    default:
        break;
    }
}
MyButton* MyButton::UpdateFatherHeight(MyButton *TreeRoot){
    cout<<GetHeight(TreeRoot->lchild)<<endl;
    TreeRoot->Height = max(GetHeight(TreeRoot->lchild), GetHeight(TreeRoot->rchild)) + 1;
    cout<<GetBalancedFactor(TreeRoot)<<endl;
    TreeRoot = Rotate(TreeRoot);
    if(TreeRoot->father != NULL)
        UpdateFatherHeight(TreeRoot->father);
}
